
/****************************************************************************
**
** Copyright (C) 2004-2008 VATATA.com . All rights reserved.
**
** This file is the part of the Miniutil Poject of VATATA.com.
** Vatata's miniutil library is lightweight and portable (for linux
** and Windows). The C++ Class Library included Threadpool, Dll danymic loading, 
** General socket application model and tcp server, httpserver/servlet, etc. 
** It is a pratical utility disigned for who don't want learn the Big C++ 
** Developing Platform, such as  Boost or ACE.
**
** This file may be used under the terms of the GNU General Public
** License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file.  Alternatively you may (at
** your option) use any later version of the GNU General Public
** License if such license has been publicly approved by VATATA.com.
** (or its successors, if any) and the Miniutil Project Aministrators. 
**
** Please review the following information to ensure GNU General
** Public Licensing requirements will be met:
** http://www.gnu.org/licenses/lgpl.html. If you are unsure which 
** license is appropriate for your use, please review the following 
** information: http://code.google.com/p/miniutil/ or contact 
** http://www.vatata.com.
**
** In addition, as a special exception, VATATA.com, as the sole
** copyright holder for Miniutil Project, grants users of VATATA
** P2P Platform the right to release and package with the related 
** libraries without the source code.
**
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE. vatata reserves all rights not expressly
** granted herein.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/



#include "miniutil/rudp.h"

#include "miniutil/threadpool.h"

#include "minitest/testcase.h"

#include <iostream>

#if 0
using namespace miniutil;
using namespace miniutil::net;



class recvThread : public runnable
{
	miniutil::usocket recvSock;

public:
	bool isRun ;
	void run()
	{
		isRun = true;
		recvSock.bind( 3456 );

		miniutil::soaddr saddr;
		char buf[1030];
		while( isRun )
		{
			int len = recvSock.recvfrom(  buf, 1030, saddr );

			cout << "recv len " << len << " seq " << *(unsigned short *) (buf+2) << endl;
		}

	}
};


class recvThread2 : public runnable
{
	miniutil::usocket recvSock;

public:
	bool isRun ;
	void run()
	{
		isRun = true;
		recvSock.bind( 3456 );

		miniutil::soaddr saddr;
		char buf[2000];
		while( isRun )
		{
			int len1 = recvSock.recvfrom(  buf, 2, saddr );
			
			unsigned short slen = *(unsigned short *) buf;

			int len = recvSock.recvfrom( buf+2, slen - 2, saddr );

			cout << "recv len " << len1 << " :" << len << " seq " << *(unsigned short *) (buf+2) << endl;
		}

	}
};

class rudpdev1 : public testcase
{

public: 
	rudpdev1()
	{
		themain.tests.push_back( this );
	}

	void test()
	{
//		testclient1();

		testrecvier1();

	}

	void testrecvier1()
	{
		miniutil::usocket usock;
		usock.bind( 4567 );

		miniutil::usocket uclientsock;
		miniutil::soaddr  dest( 4567, miniutil::ip4addr( "127.0.0.1" ) );

		usender usder( &uclientsock, &dest, 111 );
		cout << "test usender 1 ... \n";

		char buf[10000];
		memset( buf, 'c', 10000 );

		usder.send( buf, 8900 );

		cout << "test testrecvier1 ...\n";

		miniutil::net::urecvier urer( &usock, 111 );
		for(;;)
		{
			upacket *p = urer._recv();
			if ( p == NULL )
			{
				cout << "\t\t\trecv NULL packet\n";
				return;
			}
			
			cout << "\t\t\trest reciver: session id " << *(p->psessionid) << " seq " << (*(p->psessionseq)) << " len " << (*(p->pdatalen)) << endl;
			continue;

			cout << "test session id ...\t\t";
			if ( *(p->psessionid) == 111 )
				cout << "OK"<<endl;
			else
				cout << "Fail"<<endl;

			cout << "test data len ...\t\t";
			if ( *(p->pdatalen) == 1000 || *(p->pdatalen) == 900 )
				cout << "OK"<<endl;
			else
				cout << "Fail"<<endl;
		}
	}

	void testusender2()
	{
		char buf1[2000];
		miniutil::usocket usock;
		usock.bind( 4567 );

		testusender1();

		cout << "test useder 2 ...\n";
		miniutil::soaddr faddr;
		for(;;)
		{
			int l = usock.recvfrom( buf1, 1008, faddr );
			if ( l == -1 )
				cout << "\t\t\t recv -1"<<endl;
			else
			{
				cout << "\t\t\trecvlen " << l << " session id " << (*(unsigned long *)buf1) << " seq " << (*(unsigned short*)(buf1+4)) << " len " << (*(unsigned short*)(buf1+6)) << endl;

				cout << "test session id.....\t\t";
				if ( (*(unsigned long *)buf1) == 111 )
					cout << "OK" << endl;
				else
					cout << "Fail" << endl;
				cout << "test recv data len ...\t\t";

				if ( (*(unsigned short*)(buf1+6))  == 1000 ||   (*(unsigned short*)(buf1+6))  == 900 )
					cout << "OK" << endl;
				else
					cout << "Fail" << endl;
			}
		}			

	}

	void testusender1()
	{
		miniutil::usocket usock;
		miniutil::soaddr  dest( 4567, miniutil::ip4addr( "127.0.0.1" ) );

		usender usder( &usock, &dest, 111 );
		cout << "test usender 1 ... \n";

		char buf[10000];
		memset( buf, 'c', 10000 );

		usder.send( buf, 8900 );

		int count = 0;
		std::list<upacket *>::iterator it = usder.queue.begin();
		while( it != usder.queue.end() )
		{
			printf( "\t\t\t[%d] seq %d  len %d \n", count++, *(*it)->psessionseq, *(*it)->pdatalen );
			it++;
		}
		
		cout << "check queue size ...\t\t";
		if ( usder.queue.size() == 9 )
			cout << "OK" << endl;
		else
			cout <<"Fail " << usder.queue.size() << endl;

		cout << "check last data len ...\t\t";
		if ( * ((*(usder.queue.rbegin()))->pdatalen) == 900 )
			cout << "OK" << endl;
		else 
			cout << "Fail"<<endl;

	}

	void testupacketref()
	{
		upacket pkt(1008);
	}

/*
	void testclient1()
	{
		cout << "rudp developing 3 ... "<< endl;

		rusocket csock( "127.0.0.1", 3456 );
		char buf[10000];

		memset( buf, 'c', 10000 );

		csock.write( buf, 9900 );
		thread::sleep(1000);
		csock.write( buf, 9900 );
		thread::sleep(1000);
		csock.write( buf, 9900 );
		thread::sleep(1000);
		csock.write( buf, 9900 );
		thread::sleep(1000);
		csock.write( buf, 9900 );

		printf("test client over\n");
	}

	void test4()
	{
		rusocket ssock( "127.0.0.1", 4567 );
		ssock.usock.bind( 3456 );

		thread::sleep( 60 * 1000 );
	}

	void test3()
	{
		cout << "rudp developing 3 ... "<< endl;

		rusocket csock( "127.0.0.1", 3456 );
		char buf[10000];

		memset( buf, 'c', 10000 );

		csock.write( buf, 9900 );
		thread::sleep(3000);
		csock.write( buf, 9900 );
		thread::sleep(3000);
		csock.write( buf, 9900 );
		thread::sleep(3000);

		thread::sleep(10000);
		printf("test 3 over\n");
	}

	void test2()
	{
		cout << "rudp developing ... "<< endl;

		recvThread2 rthr;
		miniutil::threadpool::RunTask( & rthr );

		rusocket csock( "127.0.0.1", 3456 );

		char buf[10000];

		memset( buf, 'c', 10000 );

		csock.write( buf, 9900 );

		thread::sleep(10000);
	}

	void test1()
	{
		cout << "rudp developing ... "<< endl;

		recvThread rthr;
		miniutil::threadpool::RunTask( & rthr );

		rusocket csock( "127.0.0.1", 3456 );

		char buf[10000];

		memset( buf, 'c', 10000 );

		csock.write( buf, 9900 );

		thread::sleep(10000);

	}

	*/

};


testcase * rudpd = new rudpdev1();

#endif
